package com.erp.print.service;

import com.erp.print.view.PrintFrame;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.printing.PDFPrintable;
import org.apache.pdfbox.printing.Scaling;
import org.springframework.stereotype.Service;

import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.standard.MediaSizeName;
import javax.print.attribute.standard.Sides;
import javax.swing.*;
import java.awt.print.Book;
import java.awt.print.PageFormat;
import java.awt.print.Paper;
import java.awt.print.PrinterJob;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;


/**
 * @author moluwangling
 * @version 2024/11/18 21:11
 * @className printService
 * @description 打印服务层
 **/
@Service
public class PrintsService {
    public static HashMap<String, PrintService> serviceMap = null;//打印机列表
    public static PrintService defaultPrintService;//默认打印机
    public static Sides sides;//单双面打印
    private static final Integer copies = 1;//打印份数
    private static Scaling scaling;//缩放形式
    private static int orientation;//页面方向

    /**
     * {
     * "scaling" : "SCALE_TO_FIT",
     * "orientation" : 1,
     * "defaultPrintService" : "Microsoft XPS Document Writer",
     * "sides" : "two-sided-long-edge"
     * }
     *
     * @param data
     */
    public void config(Map<String, Object> data) {
        if (data.get("scaling") != null) {
            String scalingBtn = data.get("scaling").toString();
            //缩放形式
            switch (scalingBtn) {
                case "1":
                    scaling = Scaling.SCALE_TO_FIT;
                    break;
                case "2":
                    scaling = Scaling.ACTUAL_SIZE;
                    break;
                case "3":
                    scaling = Scaling.SHRINK_TO_FIT;
                    break;
                case "4":
                    scaling = Scaling.STRETCH_TO_FIT;
                    break;
                default:
                    return;
            }
        }
        if (data.get("orientation") != null) {
            String orientationBtn = data.get("orientation").toString();

            if (Objects.equals(orientationBtn, "1")) {
                //单面打印
                orientation = PageFormat.PORTRAIT;
            } else if (Objects.equals(orientationBtn, "2")) {
                orientation = PageFormat.LANDSCAPE;
            }
        }
        if (data.get("sides") != null) {
            String sidesBtn = data.get("sides").toString();
            if (Objects.equals(sidesBtn, "1")) {
                //单面打印
                sides = Sides.ONE_SIDED;
            } else if (Objects.equals(sidesBtn, "2")) {
                sides = Sides.DUPLEX;
            }
        }
        if (data.get("defaultPrintService") != null) {
            String def = data.get("defaultPrintService").toString();
            defaultPrintService = serviceMap.get(def);
        }

    }

    /**
     * 获取本地的打印服务，并且设置默认打印机
     */
    public JComboBox<String> selectPrintService() {
        defaultPrintService = PrintServiceLookup.lookupDefaultPrintService();//获取默认打印机
        JComboBox<String> comboBox = new JComboBox<>();
        //获得本台电脑连接的所有打印机
        javax.print.PrintService[] printServices = PrinterJob.lookupPrintServices();
        if (printServices == null || printServices.length == 0) {
            comboBox.addItem("获取本地打印机失败，请联系管理员！");
        } else {
            for (javax.print.PrintService printService : printServices) {
                String value = printService.getName();
                if (serviceMap == null) {
                    serviceMap = new HashMap<>();
                }
                serviceMap.put(value, printService);//将打印机名称及打印机服务添加到集合
                comboBox.addItem(value);
                //将默认打印机设置为下拉选的默认选择项
                if (defaultPrintService != null && defaultPrintService.getName().equals(value)) {
                    comboBox.setSelectedItem(value);
                }
            }
        }
        return comboBox;
    }

    /**
     * 打印功能实现
     */
    public void print(InputStream file, String fileName) {
        PDDocument document = null;
        try {
            if (file == null) {
                return;
            }
            document = PDDocument.load(file);
            PrinterJob printerJob = PrinterJob.getPrinterJob();
            printerJob.setJobName(fileName);
            if (defaultPrintService == null){
//                 selectPrintService();
                 new PrintFrame().init();
                 return;
            }
            printerJob.setPrintService(defaultPrintService);//设置打印机
            //设置纸张及缩放
            PDFPrintable pdfPrintable = new PDFPrintable(document, scaling);
            //设置多页打印
            Book book = new Book();
            PageFormat pageFormat = new PageFormat();
            //设置打印方向
            pageFormat.setOrientation(orientation);//纵向
            Paper paper = getPaper();
            pageFormat.setPaper(paper);
            book.append(pdfPrintable, pageFormat, document.getNumberOfPages());
            printerJob.setPageable(book);
            printerJob.setCopies(copies);//设置打印份数
            //添加打印属性
            HashPrintRequestAttributeSet attributes = new HashPrintRequestAttributeSet();
            attributes.add(Sides.ONE_SIDED); //设置单双页
            attributes.add(MediaSizeName.ISO_A4);//默认A4纸打印
            printerJob.print(attributes);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (document != null) {
                try {
                    document.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private Paper getPaper() {
        Paper paper = new Paper();
        // 默认为A4纸张，对应像素宽和高分别为 595, 842
        int width = 595;
        int height = 842;
        // 设置边距，单位是像素，10mm边距，对应 28px
        int marginLeft = 12;
        int marginRight = 12;
        int marginTop = 12;
        int marginBottom = 12;
        paper.setSize(width, height);
        // 下面一行代码，解决了打印内容为空的问题
        paper.setImageableArea(marginLeft, marginRight, width - (marginLeft + marginRight), height - (marginTop + marginBottom));
        return paper;
    }

}
